package com.bocai.grainshop.ware.service.impl;

import com.bocai.common.exception.HasWareException;
import com.bocai.common.to.mq.StockDetailTo;
import com.bocai.common.to.mq.StockLockedTo;
import com.bocai.common.utils.R;
import com.bocai.grainshop.ware.entity.WareOrderTaskDetailEntity;
import com.bocai.grainshop.ware.entity.WareOrderTaskEntity;
import com.bocai.grainshop.ware.feign.ProductFeignService;
import com.bocai.grainshop.ware.vo.SkuHasStockVo;
import com.bocai.grainshop.ware.vo.WareSkuLockVo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bocai.common.utils.PageUtils;
import com.bocai.common.utils.Query;

import com.bocai.grainshop.ware.dao.WareSkuDao;
import com.bocai.grainshop.ware.entity.WareSkuEntity;
import com.bocai.grainshop.ware.service.WareSkuService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;


@Slf4j
@Service("wareSkuService")
public class WareSkuServiceImpl extends ServiceImpl<WareSkuDao, WareSkuEntity> implements WareSkuService {

    @Resource
    private WareSkuDao wareSkuDao;

    @Resource
    private ProductFeignService productFeignService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private WareOrderTaskDetailServiceImpl wareOrderTaskDetailService;

    @Autowired
    private WareOrderTaskServiceImpl wareOrderTaskService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<WareSkuEntity> wrapper = new QueryWrapper<>();

        String skuId = (String) params.get("skuId");
        if(StringUtils.hasText(skuId)){
            wrapper.eq("sku_id",skuId);
        }
        String wareId = (String) params.get("wareId");
        if(StringUtils.hasText(wareId)){
            wrapper.eq("ware_id",wareId);
        }

        IPage<WareSkuEntity> page = this.page(
                new Query<WareSkuEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public void savaPurchase(Long skuId, Long wareId, Integer skuNum) {
        //判断是否有该记录  是新增还是修改
        List<WareSkuEntity> list = this.list(new QueryWrapper<WareSkuEntity>().eq("sku_id", skuId).eq("ware_id", wareId));
        if(list == null || list.size() == 0){
            WareSkuEntity entity = new WareSkuEntity();
            entity.setSkuId(skuId);
            entity.setWareId(wareId);
            entity.setStock(skuNum);
            entity.setStockLocked(0);

            try {
                R info = productFeignService.info(skuId);
                Map<String,Object> skuInfo = (Map<String, Object>) info.get("skuInfo");
                if(Integer.parseInt((String) info.get("code")) == 0 ){
                    entity.setSkuName((String) skuInfo.get("skuName"));
                }
            } catch (NumberFormatException e) {

            }
            this.save(entity);
        }else {

            wareSkuDao.stock(skuId,wareId,skuNum);
        }
    }

    @Override
    public List<SkuHasStockVo> getSkuHasStock(List<Long> skuIds) {
        List<SkuHasStockVo> collect = skuIds.stream().map(obj -> {
            SkuHasStockVo skuHasStockVo = new SkuHasStockVo();
            Long stock = this.baseMapper.getStock(obj);
            skuHasStockVo.setSkuId(obj);
            skuHasStockVo.setHasStock(stock==null?false:stock>0);
            return skuHasStockVo;
        }).collect(Collectors.toList());
        return collect;
    }

    @Transactional
    @Override
    public boolean lockWare(WareSkuLockVo wareSkuLockVo){
        //保存库存锁定单 订单号
        WareOrderTaskEntity wareOrderTaskEntity = new WareOrderTaskEntity();
        wareOrderTaskEntity.setOrderSn(wareSkuLockVo.getOrderSn());
        wareOrderTaskService.save(wareOrderTaskEntity);

        //找到每个商品在那些仓库有库存
        List<SkuWareHasStock> collect = wareSkuLockVo.getLocks().stream().map((o) -> {
            SkuWareHasStock hasStock = new SkuWareHasStock();
            hasStock.setSkuId(o.getSkuId());
            List<Long> ware_id = wareSkuDao.skuWareHasStock(o.getSkuId());
            hasStock.setWareId(ware_id);
            hasStock.setNum(o.getCount());
            return hasStock;
        }).collect(Collectors.toList());

        //锁库存
        if(collect.size() > 0 && collect != null){
            for (SkuWareHasStock skuWareHasStock : collect) {
                Boolean hasStock = false;
                if(skuWareHasStock.getWareId() != null && skuWareHasStock.getWareId().size() >0){
                    //挨个仓库扣减库存
                    for (Long aLong : skuWareHasStock.getWareId()) {
                        Long count = wareSkuDao.lock(skuWareHasStock.getSkuId(),aLong,skuWareHasStock.getNum());
                        log.info("锁定结果:  {}"+count);
                        if(count != 0) {
                            //锁定成功
                            //TODO 锁定成功  项mq发送消息
                            //保存工作单数据到数据库
                            WareOrderTaskDetailEntity wareOrderTaskDetailEntity = new WareOrderTaskDetailEntity();
                            wareOrderTaskDetailEntity.setLockStatus(1);
                            wareOrderTaskDetailEntity.setTaskId(wareOrderTaskEntity.getId());
                            wareOrderTaskDetailEntity.setSkuId(skuWareHasStock.getSkuId());
                            wareOrderTaskDetailEntity.setSkuNum(skuWareHasStock.getNum());
                            wareOrderTaskDetailEntity.setWareId(aLong);
                            wareOrderTaskDetailEntity.setSkuName("");
                            wareOrderTaskDetailService.save(wareOrderTaskDetailEntity);
                            //发送消息给mq
                            StockLockedTo stockLockedTo = new StockLockedTo();
                            stockLockedTo.setId(wareOrderTaskEntity.getId());
                            StockDetailTo stockDetailTo = new StockDetailTo();
                            BeanUtils.copyProperties(wareOrderTaskDetailEntity,stockDetailTo);
                            stockLockedTo.setDetailTo(stockDetailTo);
                            rabbitTemplate.convertAndSend("stock-event-exchange","stock.locked",stockLockedTo);
                            hasStock = true;
                            break;
                        }
                    }
                }else {
                    //查询的库存不足
                    throw new HasWareException(skuWareHasStock.getSkuId());
                }
                if(hasStock == false){
                    //锁定失败
                    throw new HasWareException(skuWareHasStock.getSkuId());
                }
            }
        }
        return true;
    }


    @Data
    class SkuWareHasStock{
        private Long skuId;

        private Integer num;

        private List<Long> wareId;
    }


}